<?php
/**
 * Created by PhpStorm.
 * User: wangjie
 * Date: 2021/03/01
 * Time: 10:10AM
 */
namespace App\Api\Controllers\QfPay;

use function EasyWeChat\Kernel\Support\get_client_ip;
use function EasyWeChat\Kernel\Support\get_server_ip;
use Illuminate\Support\Facades\Log;

class PayController extends BaseController
{
    /**
     * 请求支付接口    1-成功 3-交易中
     *
     * @param $reqData['ways_source']  支付类型,alipay-支付宝;weixin-微信;jd-京东;unionpay-银联
     * @param $reqData['key']  加签key
     * @param $reqData['code']  开发唯一标识
     * @param $reqData['total_amount']  订单支付金额,单位分
     * @param $reqData['mchid']  子商户号,标识子商户身份,由钱方分配(渠道系统后台查看对应商户(非业务员)子商户号,被视为对应商户的交易)
     * @param $reqData['openid']  微信的openid或支付宝user_id
     * @param $reqData['out_trade_no']  外部订单号,开发者平台订单号,同子商户(mchid)下,每次成功调用支付(含退款)接口下单,该参数值均不能重复使用,保证单号唯一,长度不超过128字符
     * @param $reqData['auth_code']  微信或者支付宝的授权码
     * @param $reqData['pay_type']  支付类型: 支付宝扫码-800101; 支付宝反扫-800108; 支付宝服务窗支付-800107;
     *                                        微信扫码-800201; 微信反扫-800208; 微信公众号支付-800207; 微信小程序支付-800213
     *                                        QQ扫码-800601; QQ反扫-800608(暂不可用);
     *                                        云闪付扫码-800701; 云闪付反扫-800708;
     *                                        统一聚合反扫-800008
     * @param $reqData['goods_name']  否,商品名称标示,建议不超过20字,不含英文逗号等特殊字符
     * @param $reqData['limit_pay']  否,该参数值指定为no_credit,则禁止使用信用卡支付
     * @param $reqData['device_no']  否,设备唯一id
     * @param $reqData['hb_fq_num']  否	,花呗分期数(只支持6,12期)
     * @param $reqData['goods_info']  否,商品信息,建议不超过20字,不含英文逗号等特殊字符
     * @param $reqData['store_id']  否,门店号
     * @return mixed
     */
    public function payment($reqData)
    {
        $ways_source = $reqData['ways_source'] ?? '';
        $key = $reqData['key'] ?? '';
        $code = $reqData['code'] ?? '';
        $total_amount = $reqData['total_amount'] ?? '';
        $mchid = $reqData['mchid'] ?? '';
        $openid = $reqData['openid'] ?? '';
        $out_trade_no = $reqData['out_trade_no'] ?? '';
        $pay_type = $reqData['pay_type'] ?? '';
        $auth_code = $reqData['auth_code'] ?? '';

        $goods_name = $reqData['goods_name'] ?? '';
        $limit_pay = $reqData['limit_pay'] ?? '';
        $device_no = $reqData['device_no'] ?? '';
        $goods_info = $reqData['goods_info'] ?? '';
        $store_id = $reqData['store_id'] ?? '';

        if ($total_amount) $total_amount = $total_amount*100;

        $data = [
            'txamt' => $total_amount,
            'txcurrcd' => 'CNY', //币种:港币-HKD;人民币-CNY
            'pay_type' => $pay_type,
            'out_trade_no' => $out_trade_no,
            'txdtm' => date('Y-m-d H:i:s', time()), //请求交易时间,格式为：格式为：YYYY-MM-DD HH:MM:SS
            'mchid' => $mchid
        ];
        if ($openid || $pay_type == 800107) {
            $data['openid'] = $openid;
        } elseif($openid || $pay_type == 800207) {
            $data['sub_openid'] = $openid;
        }
        if ($auth_code || $pay_type == 800108 || $pay_type == 800208) $data['auth_code'] = $auth_code;

        if ($goods_name) $data['goods_name'] = $goods_name;
        if ($limit_pay) $data['limit_pay'] = $limit_pay;
        if ($device_no) $data['udid'] = $device_no;
        if ($goods_info) $data['goods_info'] = $goods_info;
        if ($store_id) $data['store_id'] = $store_id;

        list($sign, $json_data) = $this->get_sign($data, $key);
        $headers = [
            'X-QF-APPCODE' => $code,
            'X-QF-SIGN' => $sign
        ];
        $url = $this->host_url.'/trade/v1/payment';
        $headerArr = array();
        foreach($headers as $n => $v) {
            $headerArr[] = $n .':' . $v;
        }

//        Log::info('钱方支付-原始请求-params：');
//        Log::info($url);
//        Log::info($json_data);
//        Log::info($headerArr);
        $result = json_decode($this->curlRequest($url, $json_data, $headerArr), true); //1-成功 2-失败 3-交易中
//        Log::info('钱方支付-原始请求-result：');
//        Log::info($result);
        if ($result['respcd'] == 0000) { //请求下单结果返回码,0000表示下单成功;1143、1145表示交易中,需要继续查询交易结果;其他返回码表示失败
            return [
                'status' => 1,
                'message' => '成功',
                'data' => $result
            ];
        } elseif ($result['respcd'] == 1143 || $result['respcd'] == 1145) {
            return [
                'status' => 3,
                'message' => '交易中',
                'data' => $result
            ];
        } else {
            return [
                'status' => $result['respcd'],
                'message' => $this->getMessageByCode($result['respcd']),
                'data' => $result
            ];
        }
    }


    /**
     * 跳到支付页面
     *
     * @param $data['mchntnm']
     * @param $data['txamt']
     * @param $data['goods_name']
     * @param $data['pay_params']
     * @return mixed
     */
//    public function payResult($data)
//    {
//        $params = [
//            "mchntnm" => urlencode($mchntnm), //自定义商户名,若为汉字需urlencode该参数
//            "txamt" => $txamt, //金额,分为单位
//            "goods_name" => urlencode($goods_name), //自定义商品名称,若为汉字需urlencode该参数
//            "redirect_url" => urldecode(url('')), //完成后跳转地址,(urlencode处理该参数)
//            "package" => $pay_params["package"], //调用支付接口,微信返回参数
//            "timeStamp" => $pay_params["timeStamp"], //调用支付接口,微信返回参数
//            "paySign" => urlencode($pay_params["paySign"]), //调用支付接口,微信返回参数(urlencode处理该参数)
//            "appId" => $pay_params["appId"], //调用支付接口,微信返回参数
//            "nonceStr" => $pay_params["nonceStr"], //调用支付接口,微信返回参数
//            "signType" => $pay_params["signType"] //调用支付接口,微信返回参数
//        ];
//
//        $url = 'https://o2.qfpay.com/q/direct';
//
//        list($sign, $json_data) = $this->get_sign($params, $key);
//
//        $r["url"] = $url.'?'.$json_data;
//        return $r;
//    }


    /**
     * 交易查询    1-成功 2-请求下单成功 3-交易中
     *
     * 发起交易后，需要调用查询接口，获取订单的状态，直到钱方返回具体的状态信息为止，根据订单的状态进行相应的处理。
     * 默认不支持隔月订单查询，若查询隔月订单，需传入start_time、end_time（时间区间包含sysdtm时间，且区间不能跨月）参数，建议以syssn为条件进行查询
     * @param $reqData['mchid']  商户号
     * @param $reqData['key']  加签key
     * @param $reqData['code']  钱方唯一标识
     * @param $reqData['out_trade_no']  否,外部订单号查询,开发者平台订单号
     * @param $reqData['syssn']  否,钱方订单号查询,多个以英文逗号区分开
     * @param $reqData['pay_type']  否,按支付类型查询,多个以英文逗号区分开:支付宝扫码-800101; 支付宝反扫-800108; 支付宝服务窗-800107; 微信扫码-800201; 微信刷卡-800208; 微信公众号支付-800207
     * @param $reqData['respcd']  否,交易返回码,默认返回所有返回码状态的订单
     * @param $reqData['start_time']  否,开始时间,默认本月开始,格式为：YYYY-MM-DD HH:MM:SS
     * @param $reqData['end_time']  否,结束时间,默认本月结束,格式为：YYYY-MM-DD HH:MM:SS
     * @param $reqData['page']  否,页数,默认1
     * @param $reqData['page_size']  否,每页显示数量,默认显示10笔订单
     * @param $reqData['total_mark']  否,固定值“1”,查询订单总数及总页数
     * @return mixed
     */
    public function query($reqData)
    {
        $mchid = $reqData['mchid'] ?? '';
        $key = $reqData['key'] ?? '';
        $code = $reqData['code'] ?? '';

        $out_trade_no = $reqData['out_trade_no'] ?? '';
        $syssn = $reqData['syssn'] ?? '';
        $pay_type = $reqData['pay_type'] ?? '';
        $respcd = $reqData['respcd'] ?? '';
        $start_time = $reqData['start_time'] ?? '';
        $end_time = $reqData['end_time'] ?? '';
        $page = $reqData['page'] ?? '';
        $page_size = $reqData['page_size'] ?? '';
        $total_mark = $reqData['total_mark'] ?? '';

        $data = [
            'mchid' => $mchid
        ];
        if ($out_trade_no) $data['out_trade_no'] = $out_trade_no;
        if ($syssn) $data['syssn'] = $syssn;
        list($sign, $json_data) = $this->get_sign($data, $key);
        $headers = [
            'X-QF-APPCODE' => $code,
            'X-QF-SIGN' => $sign
        ];
        $url = $this->host_url.'/trade/v1/query';
        $headerArr = array();
        foreach( $headers as $n => $v ) {
            $headerArr[] = $n .':' . $v;
        }
        $result = json_decode( $this->curlRequest($url, $json_data, $headerArr), true);
//        Log::info('钱方-交易查询-result:');
//        Log::info($result);
        if ($result['respcd'] == '0000') { //
            if (isset($result['data']) && isset($result['data'][0]['respcd'])) { //data内的respcd参数返回码0000表示支付交易成功，data外的respcd参数返回码0000表示请求下单成功
//                $data_list = json_decode($return['data'], true);
                $data_list = $result['data'][0];
                if ($data_list['respcd'] == '0000') { //支付结果返回码 0000表示交易支付成功；1143、1145表示交易中，需继续查询交易结果； 其他返回码表示失败
                    return [
                        'status' => 1,
                        'message' => '交易成功',
                        'data' => $data_list
                    ];
                } elseif ($data_list['respcd'] == 1143 || $data_list['respcd'] == 1145) {
                    return [
                        'status' => 3,
                        'message' => '交易中,请稍后查询交易结果',
                        'data' => $data_list
                    ];
                } else {
                    return [
                        'status' => $data_list['respcd'],
                        'message' => $this->getMessageByCode($data_list['respcd']),
                        'data' => $data_list
                    ];
                }
            }

            return [
                'status' => 2,
                'message' => '请求下单成功',
                'data' => $result
            ];
        } else {
            return [
                'status' => $result['respcd'],
                'message' => $this->getMessageByCode($result['respcd']),
                'data' => $result
            ];
        }
    }


    /**
     * 退款    1-成功
     *
     * 退款的发起是一笔退款订单,发起退款商户当日交易余额需大于退款订单金额,建议发起退款对应原订单的syssn订单号时间与本次发起退款的时间间隔不超过30天
     * @param $reqData['key']  加签key
     * @param $reqData['code']  钱方唯一标识
     * @param $reqData['mchid']  子商户号,标识子商户身份
     * @param $reqData['trade_no']  钱方订单号,退款对应的原订单syssn
     * @param $reqData['out_trade_no']  外部订单号,同子商户(mchid)下,每次成功调用支付与退款接口,该参数值均不能重复使用,也不能与支付时的外部订单号相同,保证单号唯一,长度不超过128字符
     * @param $reqData['total_amount']  订单支付金额,单位分
     * @param $reqData['device_no']  否,设备唯一id
     * @param $reqData['ext_trade_type']  否,HF POD交易时该参数固定为‘noCryptoPosp’
     * @return mixed
     */
    public function refund($reqData)
    {
        $key = $reqData['key'] ?? '';
        $code = $reqData['code'] ?? '';
        $mchid = $reqData['mchid'] ?? '';
        $trade_no = $reqData['trade_no'] ?? '';
        $out_trade_no = $reqData['out_trade_no'] ?? '';
        $total_amount = $reqData['total_amount'] ?? '';
        if ($total_amount) $total_amount = $total_amount*100;

        $device_no = $reqData['device_no'] ?? '';
        $ext_trade_type = $reqData['ext_trade_type'] ?? '';

        $data = [
            'syssn' => $trade_no,
            'out_trade_no' => $out_trade_no . rand(1000, 9999),
            'txamt' => $total_amount,
            'txdtm' => date('Y-m-d H:i:s', time()), //请求交易时间,格式为：YYYY-MM-DD HH:MM:SS
            'mchid' => $mchid
        ];
        if ($device_no) $data['udid'] = $device_no;
        if ($ext_trade_type) $data['ext_trade_type'] = $ext_trade_type;
        list($sign, $json_data) = $this->get_sign($data, $key);
        $headers = [
            'X-QF-APPCODE' => $code,
            'X-QF-SIGN' => $sign
        ];
        $url = $this->host_url.'/trade/v1/refund';
        $headerArr = array();
        foreach( $headers as $n => $v ) {
            $headerArr[] = $n .':' . $v;
        }
        Log::info('钱方-退款-原始入参：');
        Log::info($json_data);
        $result = json_decode( $this->curlRequest($url, $json_data, $headerArr), true);
        Log::info('钱方-退款-原始结果：');
        Log::info($result);
        if ($result['respcd'] == 0000) {
            return [
                'status' => 1,
                'message' => '成功',
                'data' => $result
            ];
        } else {
            return [
                'status' => $result['respcd'],
                'message' => $this->getMessageByCode($result['respcd']),
                'data' => $result
            ];
        }
    }


}
